package cn.kwq.project_manger.service.impl;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.kwq.project_manger.dtoUtils.ResTeamDtoUtils;
import cn.kwq.project_manger.exception.UnBindWyuSystemException;
import cn.kwq.project_manger.pojo.*;
import cn.kwq.project_manger.pojo.dto.AddTeamDto;
import cn.kwq.project_manger.pojo.dto.FindTeamDto;
import cn.kwq.project_manger.pojo.dto.PageDto;
import cn.kwq.project_manger.pojo.dto.ResTeamDto;
import cn.kwq.project_manger.repostitory.*;
import cn.kwq.project_manger.service.TeamService;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class TeamServiceImpl implements TeamService {

    @Autowired
    JPAQueryFactory jpaQueryFactory;

    @Autowired
    TeamRepository teamRepository;

    @Autowired
    TeamProjectRepository teamProjectRepository;

    @Autowired
    TeamUserRepository teamUserRepository;

    @Autowired
    TagRepository tagRepository;

    @Autowired
    TeamTagRepository teamTagRepository;

    @Autowired
    ResTeamDtoUtils resDtoUtils;



    @Override
    public Boolean isCaptain(Long userId,Long teamId) {
        QTeam team=QTeam.team;
        Long captionId = (Long)jpaQueryFactory.select(team._super.createdBy)
                .from(team)
                .where(team.teamId.eq(teamId))
                .fetchOne();
        if (captionId==null){
            return false;
        }else {
            return captionId.equals(userId);
        }

    }

    @Override
    @Transactional
    public ResTeamDto AddNewTeam(AddTeamDto dto, Long userId) throws UnBindWyuSystemException {
        /*
          新增或修改队伍
         */
        Team team = dto.getTeam();
        //自动获取创建者名字
        String MakeUserName = resDtoUtils.getUserName(userId);
        team.setOriginators(MakeUserName);

        Team save = teamRepository.save(team);

        /*
          新增和绑定标签
         */
        //string转换成id，并且吧没有的新增了
        List<Long> tagIds = dto
                .getTags()
                .stream()
                .map(tagName -> resDtoUtils.getTagIdByName(tagName))//自动新增
                .toList();
        //绑定标签
        resDtoUtils.bindTags(tagIds, save.getTeamId());

        /*
          查询相关信息
         */
        //把创建者加入成为队长
        resDtoUtils.setCaption(userId,save.getTeamId());

        //构造返回体
        return resDtoUtils.Team2Res(save);
    }




    @Override
    @Transactional
    public ResTeamDto acceptJoin(Long userId, Long teamId, Long joinUserId) {
        //插入队员表
        teamUserRepository.save(TeamUser
                .builder()
                .UserId(joinUserId)
                .teamId(teamId)
                .isCaption(0)
                .build());

        //更改申请表
        QJoinTeam joinTeam=QJoinTeam.joinTeam;
        jpaQueryFactory.update(joinTeam)
                .set(joinTeam.isMembers,1)
                .where(joinTeam.joinUserId.eq(joinUserId))
                .where(joinTeam.teamId.eq(teamId))
                .execute();

        QTeam team=QTeam.team;
        Team save = jpaQueryFactory.selectFrom(team)
                .where(team.teamId.eq(teamId))
                .fetchOne();


        return resDtoUtils.Team2Res(save);
    }

    @Override
    public int isCaptionCheck(Long teamId, Long joinUserId) {
        QJoinTeam joinTeam=QJoinTeam.joinTeam;
        Integer integer = jpaQueryFactory.select(joinTeam.isMembers)
                .from(joinTeam)
                .where(joinTeam.joinUserId.eq(joinUserId))
                .where(joinTeam.teamId.eq(teamId))
                .fetchOne();
        if (integer==null){
            integer=3;
        }
        return integer;
    }

    @Override
    @Transactional
    public Boolean rejectJoin(Long userId, Long teamId, Long joinUserId) throws UnBindWyuSystemException {
        //更改申请表
        QJoinTeam joinTeam=QJoinTeam.joinTeam;
        jpaQueryFactory.update(joinTeam)
                .set(joinTeam.isMembers,0)
                .where(joinTeam.joinUserId.eq(joinUserId))
                .where(joinTeam.teamId.eq(teamId))
                .execute();
        Integer integer = jpaQueryFactory.select(joinTeam.isMembers)
                .from(joinTeam)
                .where(joinTeam.joinUserId.eq(joinUserId))
                .where(joinTeam.teamId.eq(teamId))
                .fetchOne();
        return integer != null && integer != 1;
    }

    @Override
    public PageDto findTeam(FindTeamDto dto) {
        List<Long> tagIds=null;
        List<String> tagStr = dto.getTags();
        if (tagStr != null&& !tagStr.isEmpty()){
            tagIds = resDtoUtils.getTagIdButNotAdd(tagStr);
        }
        QTeam team=QTeam.team;
        QTeamTag con=QTeamTag.teamTag;

        //DONE:  2022/12/8 0:11 具体分页数据
        List<Team> fetch = jpaQueryFactory.select(team)
                .distinct()
                .from(team)
                .leftJoin(con)
                .on(team.teamId.eq(con.teamId))
                //筛选标签
                .where(tagIds == null ? team.isNull().or(team.isNotNull()) : con.tagId.in(tagIds))
                //筛选队伍名字
                .where(dto.getTeamName() == null ? team.isNull().or(team.isNotNull()) : team.teamName.like("%" + dto.getTeamName() + "%"))
                //队伍类型
                .where(dto.getTeamType() == null ? team.isNull().or(team.isNotNull()) : team.teamType.eq(dto.getTeamType()))
                //类型 0为组织 1个人
                .where(dto.getType() == null ? team.isNull().or(team.isNotNull()) : team.type.eq(dto.getType()))
                //项目名字
                .where(dto.getTeamProjectName() == null ? team.isNull().or(team.isNotNull()) : team.teamProjectName.like("%" + dto.getTeamProjectName() + "%"))
                //审核通过
                .where(team.status.eq(1))
                //排序
                .orderBy(team._super.updateDate.desc(), team._super.createdDate.desc())
                //分页
                .offset((long) (dto.getPageNum() - 1) * dto.getPageSize())
                .limit(dto.getPageSize())
                .fetch();

        Long total = jpaQueryFactory.select(team.countDistinct())
                .from(team)
                .leftJoin(con)
                .on(team.teamId.eq(con.teamId))
                //筛选标签
                .where(tagIds == null ? team.isNull().or(team.isNotNull()) : con.tagId.in(tagIds))
                //筛选队伍名字
                .where(dto.getTeamName() == null ? team.isNull().or(team.isNotNull()) : team.teamName.like("%" + dto.getTeamName() + "%"))
                //队伍类型
                .where(dto.getTeamType() == null ? team.isNull().or(team.isNotNull()) : team.teamType.eq(dto.getTeamType()))
                //类型 0为组织 1个人
                .where(dto.getType() == null ? team.isNull().or(team.isNotNull()) : team.type.eq(dto.getType()))
                //项目名字
                .where(dto.getTeamProjectName() == null ? team.isNull().or(team.isNotNull()) : team.teamProjectName.like("%" + dto.getTeamProjectName() + "%"))
                //审核通过
                .where(team.status.eq(1))
                .fetchOne();






        return PageDto
                .builder()
                .pageDate(fetch.stream().map(save -> resDtoUtils.Team2Res(save)).toList())//转换为res对象
                .total(total)
                .build();
    }

    @Override
    public ResTeamDto findTeamById(Long teamId) {
        QTeam team=QTeam.team;
        Team t = jpaQueryFactory.selectFrom(team)
                .where(team.teamId.eq(teamId))
                .fetchOne();
        return resDtoUtils.Team2Res(t);
    }

    @Override
    public List<ResTeamDto> findMyTeam(Long userId) {
        QTeam team=QTeam.team;
        List<Team> fetch = jpaQueryFactory.selectFrom(team)
                .where(team._super.createdBy.eq(userId))
                .fetch();
        return fetch.stream().map(save -> resDtoUtils.Team2Res(save)).collect(Collectors.toList());
    }

    @Override
    public List<ResTeamDto> findAllMyTeam(Long userId) {
        QTeamUser tm=QTeamUser.teamUser;
        QTeam team=QTeam.team;
        List<Team> fetch = jpaQueryFactory.selectDistinct(team)
                .from(team)
                .rightJoin(tm)
                .where(tm.UserId.eq(userId))
                .on(team.teamId.eq(team.teamId))
                .fetch();
        return fetch.stream().map(save -> resDtoUtils.Team2Res(save)).collect(Collectors.toList());
    }

}
